package com.revzone.demo001.shiro;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.revzone.demo001.config.JWTUtil_old;
import com.revzone.demo001.entity.User;
import com.revzone.demo001.mapper.PermissionMapper;
import com.revzone.demo001.mapper.RoleMapper_old;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.*;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import com.revzone.demo001.service.UserService_old;
import com.revzone.demo001.mapper.UserMapper_old;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
@Data
@EqualsAndHashCode(callSuper = false)
//@Component
public class UserRealm extends AuthorizingRealm {

    // 假设您有一个 UserService 来获取用户和角色信息
    @Autowired
    private UserService_old userService; // 您的用户服务
    @Autowired
    private RoleMapper_old RoleMapper;
    @Autowired
    private UserMapper_old userMapper;
    @Autowired
    private PermissionMapper permissionMapper;

    /**
     * 必须重写此方法，重写 supports 方法，声明支持 JWTToken 类型的认证令牌***
     */
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof JWTToken;
    }

    /**
     * 授权：获取用户的角色和权限
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        String username = JWTUtil_old.getUsername(principals.toString());
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();

        // 1. 从数据库获取用户的角色
        String currentrole = RoleMapper.getRole(username); // 假设此方法返回用户的角色名
        // 设置该用户拥有的角色和权限
        Set<String> roleSet = new HashSet<>();
        roleSet.add(currentrole);
        authorizationInfo.setRoles(roleSet);

        // 2. 获取用户拥有的权限码 (Shiro Permissions)
        // 这是关键：根据用户名（或用户ID）获取所有权限码，比如 "user:list", "user:add"
        List<String> permissionCodes = userMapper.getUserPermissionCodesbyname(username); // 假设有此方法
        Set<String> stringPermissions = new HashSet<>(permissionCodes);
        authorizationInfo.setStringPermissions(stringPermissions);


        return authorizationInfo;
    }
/**
 * 只有当需要检测用户权限的时候才会调用此方法，例如checkRole,checkPermission，@RequiresRoles("admin")之类的
 */
    /**
     * 认证：验证用户身份
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//        logger.info("————身份认证————");
        String token = (String) authenticationToken.getCredentials();

        // 解密获得username，用于和数据库进行对比
        String username = JWTUtil_old.getUsername(token);
        if (username == null || !JWTUtil_old.verify(token, username)) {
//            throw new AuthenticationException("token失效，请重新登录");
            throw new IncorrectCredentialsException("token失效，请重新登录");
        }

        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("user_name",username);
        User user = userMapper.selectOne(wrapper);

        if (user.getPassword() == null) {
//            throw new AuthenticationException("该用户不存在！");
            throw new UnknownAccountException("该用户不存在！");
        }

        if (user.getStatus() == 1) {
//            throw new AuthenticationException("该用户已被封号！");
            throw new LockedAccountException("该用户已被封号！");
        }

        // 返回认证信息
        return new SimpleAuthenticationInfo(token, token, "MyRealm");
    }
}
